#ifndef SOCK5_CONNECTEVENT_HPP
#define SOCK5_CONNECTEVENT_HPP

#include "connectiobuffer.hpp"
#include "eventhandler.hpp"
#include "ipaddress.hpp"
#include <event2/dns.h>

namespace oraysock5 {
/**
     * @brief 接收服务器数据处理器
    */
class ConnectEvent {
public:
    /**
         * @brief 构造
         * @param connect_addr 需要连接的服务器地址
         * @param type SOCK_STREAM,SOCK_DGRAM
        */
    ConnectEvent(std::shared_ptr<IPAddress> connect_addr,
        __socket_type type = SOCK_STREAM);

    /**
         * @brief 构造
         * @param hostname 服务器主机名
         * @param port 端口
         * @param type SOCK_STREAM,SOCK_DGRAM
        */
    ConnectEvent(const char* hostname, short port,
        __socket_type type = SOCK_STREAM);
    ~ConnectEvent();
    /**
         * @brief 获取socket类型 SOCK_STREAM,SOCK_DGRAM
         * @return SOCK_STREAM,SOCK_DGRAM
        */
    __socket_type type() const { return type_; };
    /*
		* 获取连接的服务器地址
        * @return 连接的服务器地址
		*/
    std::shared_ptr<IPAddress> connect_addr() const { return connect_addr_; }

    /**
         * @brief 连接成功回调
        */
    virtual void success() = 0;
    /**
         * @brief socket数据已经保存到管理io缓冲,可以读取回调
         * @return 返回SUCCESS正常没有操作,
         返回INITIATIVE_CLOSE服务器将关闭底层socket，并触发close(CLIENT_CLOSE)
         返回PASSIVE_CLOSE服务器将关闭底层socket，并触发close(SERVER_CLOSE)
        */
    virtual InputResult input() = 0;
    /**
         * @brief 指定数据已经完成发送到管理io缓冲回调
         * @return  返回0正常没有操作
         返回-1服务器将关闭底层socket，并触发close(CLIENT_CLOSE)
        */
    virtual int output() { return 0; };
    /**
         * @brief 服务器连接断开回调
         * @param active 断开原因 CLIENT_CLOSE,SERVER_CLOSE,TIMEOUT_CLOSE
        */
    virtual void close(CloseType active) = 0;
    /**
         * @brief 检测到与服务器没有心跳超时回调
         * @param active 断开原因 TIMEOUT_CLOSE
        */
    virtual void timerout(CloseType active) = 0;

    /**
         * @brief 获取端口
         * @return 端口
        */
    short dnsport() const { return dnsport_; };
    /**
         * @brief 获取连接的主机名
         * @return 连接的主机名
        */
    std::string hostname() const { return hostname_; };

    /**
         * @brief 获取dns对象
         * @return dns对象
        */
    evdns_base* dnsbase() const { return dnsbase_; };
    /**
         * @brief 设置dns对象
         * @param base dns对象 
        */
    void set_dnsbase(evdns_base* base) { dnsbase_ = base; };

private:
    /**
         * @brief 需要连接的服务器地址
        */
    std::shared_ptr<IPAddress> connect_addr_ = nullptr;
    /**
         * @brief SOCK_STREAM,SOCK_DGRAM
        */
    __socket_type type_;
    /**
         * @brief dns对象
        */
    evdns_base* dnsbase_ = nullptr;
    /**
         * @brief 端口
        */
    short dnsport_ = 0;
    /**
         * @brief 连接的主机名
        */
    std::string hostname_;
};
}

#endif
